#include "WebService.h"
#include <windows.h>
#include <fstream>

using namespace MSXML2;

/**
Constructeur
*/
WebService::WebService(void)
{
}

/**
Destructeur
*/
WebService::~WebService(void)
{
}

/**
Recupere l'URL d'une large image
@param[in]	bstrFile	contenue XML
*/
BSTR WebService::getUrlLargeImage( const BSTR bstrFile )
{
	IXMLDOMDocument2Ptr pXMLDoc = NULL;
	HRESULT hr = pXMLDoc.CreateInstance("Msxml2.DOMDocument.4.0");
	SUCCEEDED(hr) ? 0 : throw hr;
	//	Load the document synchronously
	pXMLDoc->async = false;
	//	Load the XML document
	VARIANT_BOOL vb = pXMLDoc->loadXML( bstrFile );
	( vb == VARIANT_TRUE ) ? 0 : throw 1;

	MSXML2::IXMLDOMNodePtr pXMLNode = NULL;	

	pXMLDoc->get_documentElement( (MSXML2::IXMLDOMElement**)&pXMLNode );	
	
	MSXML2::IXMLDOMNodePtr pXMLItems = XML::getUniqueChild( pXMLNode, L"Items" );
	//std::vector<MSXML2::IXMLDOMNodePtr> childs;
	MSXML2::IXMLDOMNodePtr pXMLItem = XML::getUniqueChild( pXMLItems, L"Item" );
	MSXML2::IXMLDOMNodePtr pXMLLargeImage = XML::getUniqueChild( pXMLItem, L"LargeImage" );
	MSXML2::IXMLDOMNodePtr pXMLUrl = XML::getUniqueChild( pXMLLargeImage, L"URL" );
	BSTR text;
	pXMLUrl->get_text( &text );
	return text;
}

/**
Recupere le premier identifiant
@param[in]	bstrFile	contenue XML
*/
BSTR WebService::getFirstID( const BSTR bstrFile )
{
	/*
	//Save file
	std::wofstream file(TEXT("out.xml"));
	file << _bstr_t(bstrString);
	file.close();
	*/

	IXMLDOMDocument2Ptr pXMLDoc = NULL;
	HRESULT hr = pXMLDoc.CreateInstance("Msxml2.DOMDocument.4.0");
	SUCCEEDED(hr) ? 0 : throw hr;
	//	Load the document synchronously
	pXMLDoc->async = false;
	//	Load the XML document
	VARIANT_BOOL vb = pXMLDoc->loadXML( bstrFile );
	( vb == VARIANT_TRUE ) ? 0 : throw 1;

	MSXML2::IXMLDOMNodePtr pXMLNode = NULL;	

	pXMLDoc->get_documentElement( (MSXML2::IXMLDOMElement**)&pXMLNode );	
	
	MSXML2::IXMLDOMNodePtr pXMLItems = XML::getUniqueChild( pXMLNode, L"Items" );
	std::vector<MSXML2::IXMLDOMNodePtr> childs;
	XML::getChilds( childs, pXMLItems, L"Item" );
	for each( MSXML2::IXMLDOMNodePtr pXMLNode in childs )
	{
		MSXML2::IXMLDOMNodePtr pXMLAsin = XML::getUniqueChild( pXMLNode, L"ASIN" );			
		BSTR bstrAsin;
		pXMLAsin->get_text( &bstrAsin );
		return bstrAsin;
	}
	return L"";
}

/**
Appel une requete sur le webservice
@param[in]	url	URL webservice
@param[in]	req requete
*/
BSTR WebService::request( const std::wstring& url, const std::map<std::wstring,std::wstring>& req )
{
	std::wstring str = url + TEXT("?");	
	for each( std::pair<std::wstring,std::wstring> p in req )
	{
		str += p.first + TEXT("=") + p.second;
		str += TEXT("&");
	}

	IXMLHTTPRequestPtr pIXMLHTTPRequest = NULL;
	BSTR bstrString = NULL;
	HRESULT hr;

	try 
	{
		hr = pIXMLHTTPRequest.CreateInstance("Msxml2.XMLHTTP.4.0");
		SUCCEEDED(hr) ? 0 : throw hr;

		hr=pIXMLHTTPRequest->open("GET", str.c_str(), false);
		SUCCEEDED(hr) ? 0 : throw hr;

		hr=pIXMLHTTPRequest->send();
		SUCCEEDED(hr) ? 0 : throw hr;

		return pIXMLHTTPRequest->responseText;

		if(bstrString)
		{
			::SysFreeString(bstrString);
			bstrString = NULL;
		}

	} catch (...) {
		MessageBox(NULL, TEXT("Exception occurred"), TEXT("Error"), MB_OK);
		if(bstrString)
			::SysFreeString(bstrString);
	}
	return L"";
}

namespace XML {
void getChilds( std::vector<MSXML2::IXMLDOMNodePtr>& childs,
						 MSXML2::IXMLDOMNodePtr& pXMLNode,
						 const std::wstring& str )
{
		MSXML2::IXMLDOMNodeList* list;
		pXMLNode->get_childNodes( &list );
		long size = list->length;
		for (long  i=0; i<size; i++ )
		{
			MSXML2::IXMLDOMNodePtr pXMLChildNode = list->item[i];
			BSTR text;
			HRESULT hr = pXMLChildNode->get_baseName(&text);
			if ( hr == S_OK )
			{
				if ( str == text )
				{
					childs.push_back( pXMLChildNode );
				}
			}
		}
}

MSXML2::IXMLDOMNodePtr getUniqueChild( MSXML2::IXMLDOMNodePtr& pXMLNode, const std::wstring& str )
{
	std::vector<MSXML2::IXMLDOMNodePtr> childs;
	getChilds( childs, pXMLNode, str );
	return childs.at(0);
}

}